home *** CD-ROM | disk | FTP | other *** search
/ Game Programming in C++ - Start to Finish / GameProgrammingS.iso / developer_install / CEGUISDK-0.4.1-VC6-STLport.exe / {app} / include / CEGUIEvent.h < prev    next >
C/C++ Source or Header  |  2005-10-02  |  10KB  |  377 lines

  1. /************************************************************************
  2.     filename: CEGUIEvent.h
  3.     created:  15/10/2004
  4.     authors:  Paul D Turner (High-level design) 
  5.             Gerald Lindsly (Coder)
  6.     
  7.     purpose:  Defines interface for Event class
  8. *************************************************************************/
  9. /*************************************************************************
  10.     Crazy Eddie's GUI System (http://www.cegui.org.uk)
  11.     Copyright (C)2004 - 2005 Paul D Turner (paul@cegui.org.uk)
  12.  
  13.     This library is free software; you can redistribute it and/or
  14.     modify it under the terms of the GNU Lesser General Public
  15.     License as published by the Free Software Foundation; either
  16.     version 2.1 of the License, or (at your option) any later version.
  17.  
  18.     This library is distributed in the hope that it will be useful,
  19.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  21.     Lesser General Public License for more details.
  22.  
  23.     You should have received a copy of the GNU Lesser General Public
  24.     License along with this library; if not, write to the Free Software
  25.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  26. *************************************************************************/
  27. #ifndef _CEGUIEvent_h_
  28. #define _CEGUIEvent_h_
  29.  
  30. #if defined (_MSC_VER)
  31. #    pragma warning(push)
  32. #    pragma warning(disable : 4786)
  33. #    pragma warning(disable : 4251)
  34. #    if !defined (_MSC_EXTENSIONS)
  35. #        pragma warning (disable : 4224)
  36. #    endif
  37. #endif
  38.  
  39. #include "CEGUIBase.h"
  40. #include "CEGUIString.h"
  41. #include "CEGUIEventArgs.h"
  42. #include "CEGUIRefPtr.h"
  43.  
  44. #include <map>
  45.  
  46.  
  47. // Start of CEGUI namespace section
  48. namespace CEGUI
  49. {
  50.  
  51. /*!
  52. \brief
  53.     The base class for the various binders.  This provides a consistent
  54.     interface for firing functions bound to an event.
  55. */
  56. template <typename Ret, typename Args>
  57. class SubscriberInterface {
  58. public:
  59.   virtual Ret operator()(Args) const = 0;
  60.   virtual ~SubscriberInterface() {}
  61. };
  62.  
  63.  
  64. /*!
  65. \brief
  66.     This class binds a free function.
  67. */
  68. template <typename Ret, typename Args>
  69. class _freeBinder : public SubscriberInterface<Ret,Args>
  70. {
  71. public:
  72.   virtual Ret operator()(Args args) const 
  73.   {
  74.     return d_f(args);
  75.   }
  76.   typedef Ret (*SlotFunction)(Args);
  77.   _freeBinder(SlotFunction f) : d_f(f) {}
  78. protected:
  79.   SlotFunction d_f;
  80. };
  81.  
  82.  
  83. /*!
  84. \brief
  85.     This class binds a copy of a functor.
  86. */
  87. template <class Functor, typename Ret, typename Args>
  88. class _functorBinder : public SubscriberInterface<Ret,Args>
  89. {
  90. public:
  91.   virtual Ret operator()(Args args) const 
  92.   {
  93.     return d_f(args);
  94.   }
  95.   _functorBinder(const Functor& f) : d_f(f) {}
  96. protected:
  97.   Functor d_f;
  98. };
  99.  
  100.  
  101. /*!
  102. \brief
  103.     This class binds a member function along with a target object.
  104. */
  105. template <class T, typename Ret, typename Args>
  106. class _memberBinder : public SubscriberInterface<Ret,Args>
  107. {
  108.   typedef Ret (T::*F)(Args);
  109. public:
  110.   virtual Ret operator()(Args args) const
  111.   {
  112.     return (d_t->*d_f)(args);
  113.   }
  114.   _memberBinder(F f, T* t) : d_f(f), d_t(t) {}
  115. protected:
  116.   F  d_f;
  117.   T* d_t;
  118. };
  119.  
  120.  
  121. /*!
  122. \brief
  123.     This template describes the Subscriber class.  It is a wrapper
  124.     for a pointer to a SubscriberInterface with various constructors
  125.     that will by implicit conversion construct the various binders.
  126. */
  127. template <typename Ret, typename Args>
  128. class SubscriberTemplate
  129. {
  130. public:
  131.   Ret operator()(Args args) const
  132.   {
  133.     return (*d_si)(args);  // call the bound function
  134.   }
  135.  
  136.   typedef Ret (*SlotFunction)(Args);
  137.  
  138.   //! construct from a free function
  139.   SubscriberTemplate(SlotFunction f)
  140.   {
  141.     d_si = new _freeBinder<Ret,Args>(f);
  142.   }
  143.  
  144.   //! construct from a member function and a pointer to the target object.
  145.   template <class T>
  146.   SubscriberTemplate(Ret (T::*f)(Args), T* target)
  147.   {
  148.     d_si = new _memberBinder<T,Ret,Args>(f, target);
  149.   }
  150.  
  151.   //! construct from a generalized functor by copying it
  152.   template <typename Functor> 
  153.   SubscriberTemplate(const Functor& f)
  154.   {
  155.     d_si = new _functorBinder<Functor,Ret,Args>(f);
  156.   }
  157.  
  158.   /*!
  159.   \brief
  160.     construct from a preconstructed SubscriberInterface.
  161.     used for SubscriberRef().
  162.   */
  163.   SubscriberTemplate(SubscriberInterface<Ret,Args>* si) : d_si(si) {}
  164.  
  165.   //! copy constructor
  166.   SubscriberTemplate(const SubscriberTemplate<Ret,Args>& copy) : d_si(copy.d_si) {}
  167.  
  168.   //! 'less than' comparable for insertion in a map
  169.   bool operator<(const SubscriberTemplate<Ret,Args>& rhs) const { return d_si < rhs.d_si; }
  170.  
  171.   //! release the binding -- called upon disconnection
  172.   void release() const
  173.   {
  174.     delete d_si;
  175.   }
  176.  
  177. protected:
  178.   SubscriberInterface<Ret,Args>* d_si;
  179. };
  180.  
  181.  
  182. /*!
  183. \brief
  184.     This class binds a const reference to a generalized functor.
  185.     Sometimes it may not be appropriate for the functor to be
  186.     cloned.  In which case, use SubscriberRef() (which uses this).
  187. */
  188. template <class Functor, typename Ret, typename Args>
  189. class _refBinder : public SubscriberInterface<Ret,Args>
  190. {
  191. public:
  192.   virtual Ret operator()(Args args) const
  193.   {
  194.     return d_f(args);
  195.   }
  196.   _refBinder(const Functor& f) : d_f(f) {}
  197. protected:
  198.   const Functor& d_f;
  199. };
  200.  
  201. /*!
  202. \brief
  203.     This helper function produces a const reference binding
  204. */
  205. template <class Functor>
  206. SubscriberInterface<bool, const EventArgs&>*
  207. SubscriberRef(const Functor& f)
  208. {
  209.   return new _refBinder<Functor,bool,const EventArgs&>(f);
  210. }
  211.  
  212.  
  213. /*!
  214. \brief
  215.     Defines an 'event' which can be subscribed to by interested parties.
  216.  
  217.     An Event can be subscribed by a function, a member function, or a function object.  Whichever option
  218.     is taken, the function signature needs to be as follows
  219.     \par
  220.     <em>bool function_name(const EventArgs& args);</em>
  221.     \note
  222.         An Event object may not be copied.
  223. */
  224. class CEGUIEXPORT Event
  225. {
  226. public:
  227.     /*!
  228.     \brief
  229.         Interface to be implemented by connection objects.
  230.     */
  231.     class ConnectionInterface : public Referenced {
  232.     public:
  233.         virtual bool connected() { return false; }
  234.         virtual void disconnect() {}
  235.     };
  236.     typedef RefPtr<ConnectionInterface> Connection;
  237.  
  238.     /*!
  239.     \brief
  240.         A Connection object that automatically disconnects from the event
  241.         when the ScropedConnection object goes out of scope (and is deleted).
  242.     */
  243.     class ScopedConnection {
  244.     public:
  245.         ScopedConnection(Connection conn_) : conn(conn_) {}
  246.         ~ScopedConnection() { conn->disconnect(); }
  247.         Connection conn;
  248.     };
  249.  
  250.  
  251.     typedef SubscriberTemplate<bool, const EventArgs&> Subscriber;
  252.     typedef int Group;
  253.  
  254.     /*************************************************************************
  255.         Construction and Destruction
  256.     *************************************************************************/
  257.     /*!
  258.     \brief
  259.         Constructs a new Event object with the specified name
  260.     */
  261.     Event(const String& name);
  262.  
  263.     /*!
  264.     \brief
  265.         Destructor for Event objects
  266.     */
  267.     virtual ~Event(void);
  268.  
  269.  
  270.     /*!
  271.     \brief
  272.         Return the name given to this Event object when it was created.
  273.  
  274.     \return
  275.         String object containing the name of the Event object.
  276.     */
  277.     const String& getName(void) const    {return d_name;}
  278.  
  279.  
  280.     /*!
  281.     \brief
  282.         Subscribes some function / object to the Event
  283.  
  284.     \param subscriber
  285.         A function, static member function, or function object, with the signature void function_name(const EventArgs& args)
  286.  
  287.     \return
  288.         A Connection pointer which can be used to disconnect (unsubscribe) from the Event, and to check the connection state.
  289.     */
  290.     Connection subscribe(Subscriber subscriber) { return subscribe(0, subscriber); }
  291.  
  292.  
  293.     /*!
  294.     \brief
  295.         Subscribes some function / object to the Event
  296.  
  297.     \param group
  298.         The Event group to subscribe to, subscription groups are called in ascending order, followed by subscriptions with no group.
  299.         connections to the same group may be called in any order.
  300.  
  301.     \param subscriber
  302.         A function, static member function, or function object, with the signature void function_name(const EventArgs& args)
  303.  
  304.     \return
  305.         A Connection which can be used to disconnect (unsubscribe) from the Event, and to check the connection state.
  306.     */
  307.     Connection subscribe(Group group, Subscriber subscriber);
  308.   
  309.  
  310.     /*
  311.     \brief
  312.         Fires the event.  All event subscribers get called in the appropriate sequence.
  313.  
  314.     \param args
  315.         An object derived from EventArgs to be passed to each event subscriber.
  316.  
  317.     \return
  318.         Nothing.
  319.     */
  320.     void    operator()(EventArgs& args);
  321.  
  322. private:
  323.     /*************************************************************************
  324.         Copy constructor and assignment are not allowed for events
  325.     *************************************************************************/
  326.     Event(const Event& evt)    {}
  327.     Event& operator=(const Event& evt)    {return *this;}
  328.  
  329.     /*
  330.     \brief
  331.         removes the subscriber from the event.
  332.  
  333.     \param subscriber
  334.         A pointer to a SubscriberInterface which is to be removed from the event.
  335.  
  336.     \return
  337.         - true, if the subscriber was registered with the event in the specified group and it was removed.
  338.         - false, if not.
  339.     */
  340.     bool unsubscribe(Subscriber subscriber, Group group=0);
  341.  
  342.     class GroupSubscriber {
  343.     public:
  344.         Group group;
  345.         Subscriber subscriber;
  346.         GroupSubscriber(Group group_, Subscriber subscriber_) 
  347.             : group(group_), subscriber(subscriber_) {}
  348.     };
  349.  
  350.     struct ltGroupSubscriber
  351.     {
  352.         bool operator()(const GroupSubscriber& gs1, const GroupSubscriber& gs2) const
  353.         {
  354.             return gs1.group <  gs2.group ||
  355.                 gs1.group == gs2.group && gs1.subscriber < gs2.subscriber;
  356.         }
  357.     };
  358.     typedef std::map<GroupSubscriber, Connection, ltGroupSubscriber> ConnectionOrdering;
  359.  
  360.  
  361.     /*************************************************************************
  362.         Implementation Data
  363.     *************************************************************************/
  364.     const String    d_name;        //!< Name of this event
  365.     ConnectionOrdering connectionOrdering;
  366.     friend class ConnectionImpl;
  367. };
  368.  
  369.  
  370. } // End of  CEGUI namespace section
  371.  
  372. #if defined(_MSC_VER)
  373. #    pragma warning(pop)
  374. #endif
  375.  
  376. #endif    // end of guard _CEGUIEvent_h_
  377.